package com.xinz.srmi.impl;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.Socket;
import java.net.SocketException;
import java.net.URL;

import com.xinz.srmi.Buffer;
import com.xinz.srmi.ConfigFactory;
import com.xinz.srmi.InvokeConnector;
import com.xinz.srmi.Log;
import com.xinz.srmi.NativeInterfaceProvider;
import com.xinz.srmi.NativeInvoker;
import com.xinz.srmi.RemoteInvoker;
import com.xinz.srmi.Session;
import com.xinz.srmi.SrmiClient;
import com.xinz.srmi.SrmiDefine;
/**
 * SRMI Socket连接客户端的简单实现
 * 初始化之后通过connect方法来连接服务端<br>
 * 一个SimpleSocketClient对象对应一个连接session。<br>
 * 目前方法调用是单通道的，这也意味着同一时刻只有一个方法被调用
 * 
 * @author xingyun
 *
 */
public class SimpleHttpClient extends SrmiClient{
	URL url;
	long sessionID = 0;
//	SocketChannel channel;
	public SimpleHttpClient(URL url, ConfigFactory foctyoy){
		super(foctyoy);
		this.url = url;
	}
	@Override
	public void run() {
		try{
			while(true){
				try{
					Thread.sleep(1000);
					HttpURLConnection conn = openConnection();
					doPrase(conn.getInputStream());
				}catch (Exception e) {
					e.printStackTrace();
				}
			}
		}catch (Exception e) {
			e.printStackTrace();
		}
	}
	HttpURLConnection openConnection() throws IOException{
		HttpURLConnection conn = (HttpURLConnection)url.openConnection();
		conn.setRequestMethod("POST");
		conn.setDoInput(true);
		conn.setDoOutput(true);
//		conn.setReadTimeout(15000);
//		conn.setConnectTimeout(10000);
		conn.connect();
		DataOutputStream dos = new DataOutputStream(conn.getOutputStream());
		dos.writeLong(sessionID);
		return conn;
	}
	
	Buffer doPrase(InputStream is) throws IOException{
		DataInputStream dis = new DataInputStream(is);
		sessionID = dis.readLong();//读取sessionID
		int pakSize = dis.readShort();
		Buffer result = null;
		for(int i=0;i<pakSize;i++){
			int type = dis.read();
			int length = dis.readShort();
			byte buff[] = new byte[length];
			dis.readFully(buff);
			Buffer buffer = new Buffer(buff, type);
			if(type==SrmiDefine.TYPE_REQUEST_NORETURN){
				nativeInvoker.invoke(getSession(),buffer);
			}else if(type==SrmiDefine.TYPE_RETURN){
				if(result!=null) throw new RuntimeException();
				result = buffer;
			}
		}
		return result;
	}
	
	@Override
	public Buffer request(Buffer request) throws IOException {
		request.type = SrmiDefine.TYPE_REQUEST;
		HttpURLConnection conn = null;
		InputStream is = null;
		try {
			conn = openConnection();
			OutputStream out =null;
			try{
				out = conn.getOutputStream();
				out.write(request.type);
				request.writeToStream(out);
				out.flush();
			}finally{
				if(out!=null){
					out.close();
				}
			}
			is = conn.getInputStream();
			return doPrase(is);
		} catch (IOException e) {
			Log.err("连接服务器失败！ url："+url);
			e.printStackTrace();
			throw e;
		}finally{
			try {
				is.close();
			}catch (Exception e) { }
			if(conn!=null)conn.disconnect();
		}
	}
}
